package it.fuesi.expired.api.client.base;

import it.fuesi.expired.model.base.IModel;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.BufferedImageHttpMessageConverter;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

public abstract class AClientBroker {

	private String endpoint;
	private String resourceUri;

	public AClientBroker(String endpoint) {
		this.endpoint = endpoint;
		this.resourceUri = getResourceUri();
	}

	protected abstract String getResourceUri();

	protected <T extends IModel> ResponseEntity<T> execute(String uri,
			HttpMethod method, HttpEntity<?> request, Class<T> responseType,
			Map<String, Object> uriVariables) {

		final String url = endpoint + uri;

		final RestTemplate restTemplate = getRestTemplate();

		if (uriVariables != null)
			return restTemplate.exchange(url, method, request, responseType,
					uriVariables);
		else
			return restTemplate.exchange(url, method, request, responseType);
	}

	protected <T extends IModel> ResponseEntity<T> execute(String uri,
			HttpMethod method, HttpEntity<?> request, Class<T> responseType) {

		return execute(uri, method, request, responseType, null);

	}

	protected String getEndpoint() {
		return this.endpoint;
	}

	protected RestTemplate getBasicByteArrayRestTemplate(){
		List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
		ByteArrayHttpMessageConverter byteConv = new ByteArrayHttpMessageConverter();
//		MappingJackson2HttpMessageConverter jsonConv = new MappingJackson2HttpMessageConverter();
//		
//		FormHttpMessageConverter formConv = new FormHttpMessageConverter();
//		formConv.addPartConverter(jsonConv);
//		
		converters.add(byteConv);
		converters.add(new ResourceHttpMessageConverter());
		converters.add(new StringHttpMessageConverter());
//		
		final RestTemplate restTemplate = new RestTemplate();
		restTemplate.setMessageConverters(converters);

//		restTemplate.setMessageConverters(converters);
		
		return restTemplate;
	}
	
	protected RestTemplate getRestTemplate() {

		List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
		MappingJackson2HttpMessageConverter jsonConv = new MappingJackson2HttpMessageConverter();

		FormHttpMessageConverter formConv = new FormHttpMessageConverter();
		formConv.addPartConverter(jsonConv);

		ByteArrayHttpMessageConverter byteConv = new ByteArrayHttpMessageConverter();

		converters.add(formConv);

		converters.add(jsonConv);

		converters.add(byteConv);

		final RestTemplate restTemplate = new RestTemplate();

		restTemplate.setMessageConverters(converters);
		
		return restTemplate;
	}

}
